ES6(let 與 const、Template Literals)


Posted by saffran on 2021-02-05

ES5?ES6?這些到底是什麼

ECMAScript 就是一個「標準、規範」,開發者可以根據這個規範去開發程式語言

而 JavaScript 這個程式語言就是根據 ECMAScript 去實作的

  • ECMAScript 5 (簡稱 ES5)是比較舊的 JavaScript 語法
  • ES6 在 2015 年正式發佈,有新增一些 JavaScript 的語法、功能
    因此 ES6 又稱為 ES2015

宣告變數的新選擇:let 與 const

const

const 的全名是 constant(常數),是「不能改變」的

使用時機:
有些變數,我已經知道它是不會變的,就可以用 const 來宣告

對於 primitive type 來說,用 const 宣告的變數是「值」不能改變

例如:
我用 const 宣告變數 b (是一個 number,屬於 primitive type),變數裡面是直接存「值」

因此,變數 b 的「值」是不能改變的

如果我把變數 b 的值改成 20

console.log(b) 就會出現錯誤:Assignment to constant variable.(你不可以改變一個 constant variable)

const b = 9
b = 20

console.log(b)

對於 object 來說,用 const 宣告的變數是「記憶體位置」不能改變

(object 可以是物件或陣列)

例如:
我用 const 宣告變數 b(是一個物件,屬於 object),變數裡面存的是「記憶體位置」

因此,我用 b.number = 30 修改 number 的 value

結果發現是可以更改的!

const b = {
  number: 10
}
b.number = 30

console.log(b)
// output: { number: 30 }

原因是:
「用 const 宣告的變數,不能改變」,對於 object 來說是指:「物件/陣列裡面存的 “記憶體位置” 不能改變」,如果只是更改 b.number = 30 並沒有改動到記憶體位置,b.number = 30 只是去改「那個記憶體位置上的物件的 value」而已,因此是可以更改的!(用這種 . 的方式去修改物件裡面的值)

但是,如果是把一個「新的物件」賦予給變數 b,那就不行了,因為新的物件會是「新的記憶體位置」

例如:
下面這樣寫就會出現錯誤:Assignment to constant variable(你不可以改變一個 constant variable)

const b = {
  number: 10
}

b = {
  number: 99
}

console.log(b)

var 跟 let, const 的差別是什麼?

要了解 var 跟 let, const 的差別,首先要了解「作用域」的概念:

作用域(Scope)

作用域,就是「變數的生存範圍」

變數的運行機制:從「最近的」開始找,先找到的先贏

例如:

範例一:在 function 外面宣告變數 a

變數 a 是「全域變數」

因為我在外層宣告的變數 a 是在「檔案的這層」,所以,如果 test function 裡面沒有宣告 a,它就會往上層找,直到找到 a 為止,因此就會找到 var a = 20

var a = 20
function test(){
  console.log(a)
}

test()
// output: 20

範例二:function 裡面有宣告變數 a
因為在 test function 裡面就有宣告 a,所以它在 function 裡面就找到 a

var a = 20
function test(){
  var a = 99
  console.log(a)
}

test()
// output: 99

區域變數

因為我是在 test function 裡面宣告變數 a,所以變數 a 的作用域就只存在 test function 裡面

變數 a 是「區域變數」

test function 外面是無法使用變數 a 的

因此,console.log(a) 就會出現錯誤:a is not defined

function test(){
  var a = 20
}

test()
console.log(a)

用 var 宣告的變數,變數的作用域會是「一個 function」

例如:
雖然我是在 if 的區塊(block)宣告變數 a,但只要是在 test function 裡面,就都是變數 a 的作用域

因此,console.log(a) 可以存取到 a 的值

function test(){
  if(10 > 5){
    var a = 10
  }
  console.log(a)
}

test()
// output: 10

用 let 或是 const 宣告的變數,變數的作用域會是「一個 block」而已

例如:
用 let 宣告變數
我是在 if 的區塊(block)內,用 let 宣告變數 a,因此變數 a 的作用域就只會在 if 這個 block 內而已:

  if(10 > 5){
    let a = 10
  }

所以,在 if 區塊外面的 console.log(a) 就會出現錯誤:a is not defined

function test(){
  if(10 > 5){
    let a = 10
  }
  console.log(a)
}

test()

用 const 宣告變數
我是在 if 的區塊(block)內,用 const 宣告變數 a,因此變數 a 的作用域就只會在 if 這個 block 內而已

所以,在 if 區塊外面的 console.log(a) 就會出現錯誤:a is not defined

function test(){
  if(10 > 5){
    const a = 10
  }
  console.log(a)
}

test()

使用時機

  • 如果變數會改變,就用 let 宣告
  • 如果變數不會改變,就用 const 宣告
    例如:const PI = 3.14
  • 盡量用 let, const 來宣告變數(基本上不會需要用 var 這個關鍵字)
    原因是:會希望作用域越小越好,這樣才不容易干擾到其他變數(例如:取了同名的變數,就不會互相干擾),也比較容易 debug

字串拼接好麻煩,改用 Template Literals 吧

在 ES5 時,使用 string 會遇到幾個問題:

[問題一] 字串需要換行時

有多行字串時,無法直接換行(下面這樣寫,是會出錯的)

let str = '
hello
I
love
you
'

字串要換行就要用這種「字串拼接」的方式,很麻煩

let str = 
  'hello' + '\n' +
  'I' + '\n' +
  'love' + '\n' +
  'you'

console.log(str)

output:

hello
I
love
you

[問題二] 當我有很多字串 + 變數需要拼接時

單引號、加號如果放錯位置,就很容易造成語法錯誤,這樣很麻煩

function sayHi(name){
  console.log('Hello, ' + name + '! It is ' + new Date() + ' now.')
}

sayHi('Dan')
// output: Hello, Dan! It is Thu Jul 09 2020 15:28:20 GMT+0800 (Taipei Standard Time) now.

用 ES6 的 `` 來寫字串

字串可以直接換行,好方便

`` 這個反引號來包住字串,字串就可以直接換行了

let str = `
hello
I
love
you
`
console.log(str)

output:

hello
I
love
you

${ } 插入 JS 程式碼,好方便

${ }裡面,可以放 JavaScript 的程式碼,最常放在裡面的就是「JavaScript 的變數」

function sayHi(name){
  console.log(`Hello, ${name}! It is ${new Date()} now.`)
}

sayHi('Dan')
// output: Hello, Dan! It is Thu Jul 09 2020 15:39:22 GMT+0800 (Taipei Standard Time) now.

也可以直接在 ${ }裡面執行一些 function,例如: ${name.toUpperCase()} 就會把 name.toUpperCase() 的回傳值,放到字串裡面

function sayHi(name){
  console.log(`Hello, ${name.toUpperCase()}! It is ${new Date()} now.`)
}

sayHi('Daniel')
// output: Hello, DANIEL! It is Thu Jul 09 2020 15:43:35 GMT+0800 (Taipei Standard Time) now.

#javascript







Related Posts

物件導向設計的五個基本原則 SOLID

物件導向設計的五個基本原則 SOLID

Docker Compose 建置 Web service 起步走入門教學

Docker Compose 建置 Web service 起步走入門教學

Object get keys and values method

Object get keys and values method


Comments